package com.fingard.dsp.bank.directbank.baofoo01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IRealTime;
import com.fingard.dsp.bank.directbank.baofoo01.util.FormatUtil;
import com.fingard.dsp.bank.directbank.baofoo01.util.RsaCodingUtil;
import com.fingard.dsp.bank.directbank.baofoo01.util.SecurityUtil;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import net.sf.json.JSONObject;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class BaoFoo01RealTime extends BaoFoo01Base implements IRealTime {
	public RetAtsSingle d_9108_RealTimeRec(ReqSingle p_req9108)	throws Exception {
		if ("910801".equals(p_req9108.reqHeader.commandCode)) {//代理汇兑
			return d_910801(p_req9108);
		} else {
			return d_910802(p_req9108);
		}
	}

	/**
	 * 宝付单笔实时代收
	 */
	public RetAtsSingle d_910801(ReqSingle p_req9108) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9108.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req9108);
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9108.singleDetail.recAct, "");
			if (actItem == null) {
				throw new Exception("未找到账号" + p_req9108.singleDetail.recAct + "对应的商户配置信息");
			}
			
			Map<String,String> postParams = new HashMap<String,String>();
			
			postParams.put("version", "4.0.0.0");
			postParams.put("terminal_id", actItem.termId);
			postParams.put("txn_type", "0431");
			postParams.put("txn_sub_type", "83");
			postParams.put("member_id", actItem.merchantId);
			postParams.put("data_type", "xml");
			
			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\" ?>");
			xmlWriter.writeStartElement("data_content");
			xmlWriter.writeElementString("txn_sub_type", "83");
			
			if (p_req9108.singleDetail.cardType.equals("3")) {
				xmlWriter.writeElementString("biz_type", "0102");
			}else {
				xmlWriter.writeElementString("biz_type", "0000");
			}
			
			xmlWriter.writeElementString("terminal_id", actItem.termId);
			xmlWriter.writeElementString("member_id", actItem.merchantId);
			xmlWriter.writeElementString("pay_code", getBankConfig().getMapKeyByValue("bankMapping", p_req9108.singleDetail.payBankCode));
			xmlWriter.writeElementString("pay_cm", "2");
			xmlWriter.writeElementString("acc_no", p_req9108.singleDetail.payAct);
			xmlWriter.writeElementString("id_card_type", "01");
			xmlWriter.writeElementString("id_card", p_req9108.singleDetail.certNum);
			xmlWriter.writeElementString("id_holder", p_req9108.singleDetail.payName);
			xmlWriter.writeElementString("mobile", p_req9108.singleDetail.cellPhone);
			
			if (p_req9108.singleDetail.cardType.equals("3")) {
				xmlWriter.writeElementString("valid_data", Format.Date4YearMonth.format(p_req9108.singleDetail.expiredDate));
				xmlWriter.writeElementString("valid_no", p_req9108.singleDetail.cvv2);
			}
			
			if (p_req9108.singleDetail.askNumber == null) {
				xmlWriter.writeElementString("trans_id", "TID"+System.currentTimeMillis());
			}else {
				xmlWriter.writeElementString("trans_id", p_req9108.singleDetail.askNumber);
			}
			
			xmlWriter.writeElementString("txn_amt", StringHelper.amountMultiply100(p_req9108.singleDetail.payAmount));
			xmlWriter.writeElementString("trade_date", Format.DateTime14Format.format(new Date()));
			xmlWriter.writeElementString("additional_info", "附加信息");
			xmlWriter.writeElementString("req_reserved", "保留");
			xmlWriter.writeElementString("trans_serial_no", "TISN"+System.currentTimeMillis());	
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
			
			// 加密数据
			WriteBankLogLn2("加密数据: " + xmlWriter.toXmlString());
			
			String base64Str = Base64Encode(xmlWriter.toXmlString());
			String data_content = encryptByPriPfxFile(base64Str,actItem.ownKeyStorePath, actItem.ownKeyPassword);
			
			postParams.put("data_content", data_content);

			String tmpStrRet = sendToBank("9108", postParams);

			if (tmpStrRet.contains("trans_content")) {
				//明文返回,报文错误处理
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "报文参数设置错误";
			}else {
				String decryptStr = decryptByPubCerFile(tmpStrRet, actItem.oppCertFilePath);
				String respXml = Base64Decode(decryptStr);
				WriteBankLogStep3(respXml);

				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
				if (tmpBkReader != null) {
					String tmpRespCode = tmpBkReader.getFirstText("/result/resp_code");
					tmpRetDetail.respCode = "0";
					tmpRetDetail.respInfo = tmpBkReader.getFirstText("/result/resp_msg");
					tmpRetDetail.transState = tmpRespCode;
					tmpRetDetail.payInfoCode = tmpRespCode;
				}else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpSbMsg.toString();
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	public RetAtsSingle d_910802(ReqSingle p_req9108)	throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9108.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		try{
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9108.singleDetail.recAct, "contract");
			if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath)|| !FileHelper.existFile(actItem.oppCertFilePath)) {
				if (actItem == null) {
					throw new Exception("未找到账号" + p_req9108.singleDetail.recAct + "对应的商户配置信息");
				} else {
					throw new Exception("账号" + p_req9108.singleDetail.recAct + "对应的证书文件不存在");
				}
			}
			Map<String,String> postParams = new TreeMap<String,String>();
			postParams.put("send_time", Format.DateTimeFormat.format(new Date()));
			postParams.put("msg_id", p_req9108.singleDetail.askNumber+"1");
			postParams.put("trans_id", p_req9108.singleDetail.askNumber);
			postParams.put("version", "4.0.0.0");
			postParams.put("terminal_id", actItem.termId);
			postParams.put("txn_type", "08");
			postParams.put("member_id", actItem.merchantId);
			String dgtl_envlp = "01|"+actItem.saltKey;
			dgtl_envlp = RsaCodingUtil.encryptByPubCerFile(SecurityUtil.Base64Encode(dgtl_envlp), actItem.oppCertFilePath);//公钥加密
			postParams.put("dgtl_envlp", dgtl_envlp);
			String ProtocolNo= p_req9108.singleDetail.authCode;
			WriteBankLogLn("加密前的ProtocolNo=" + ProtocolNo);
			ProtocolNo = SecurityUtil.AesEncrypt(SecurityUtil.Base64Encode(ProtocolNo), actItem.saltKey);//先BASE64后进行AES加密
			postParams.put("protocol_no", ProtocolNo);
			postParams.put("txn_amt", StringHelper.amountMultiply100(p_req9108.singleDetail.payAmount));
			if (p_req9108.singleDetail.cardType.equals("3")) {
				String card_info = Format.Date4YearMonth.format(p_req9108.singleDetail.expiredDate)+"|"+p_req9108.singleDetail.cvv2;
				card_info = SecurityUtil.AesEncrypt(SecurityUtil.Base64Encode(card_info), actItem.saltKey);//先BASE64后进行AES加密
				postParams.put("card_info", card_info);
			}
			Map<String,String> RiskItem = new HashMap<String,String>();
			RiskItem.put("goodsCategory", "05");//商品类目 详见附录《商品类目》
			RiskItem.put("chPayIp", "127.0.0.1");//用户在商户端注册时留存的IP


			/**--------行业参数 -------**/
			RiskItem.put("applicantName",  p_req9108.singleDetail.payName);
			RiskItem.put("applicantMobile", p_req9108.singleDetail.cellPhone);
			RiskItem.put("insuranceType", getBankConfig().getValueAsString("insuranceType"));

			postParams.put("risk_item",JSONObject.fromObject(RiskItem).toString());//放入风控参数

			postParams.put("return_url", actItem.returnURL);//最多填写三个地址,不同地址用间使用‘|’分隔
			postParams.put("signature", sign(postParams,actItem));
			String[] tmpStrRet = sendToBank("contract",postParams,actItem);

			if (tmpStrRet[0].length() == 0) {
				Map<String, String> ReturnData = FormatUtil.getParm(tmpStrRet[1]);
				String resp_code = ReturnData.get("resp_code");
				String biz_resp_code = ReturnData.get("biz_resp_code");
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = ReturnData.get("biz_resp_msg");
				tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
				tmpRetDetail.transState = resp_code;
				tmpRetDetail.payInfoCode = biz_resp_code;
				tmpRetDetail.transAmt = ReturnData.get("succ_amt")==null?"":StringHelper.amountDivide100(ReturnData.get("succ_amt"));
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception e) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = e.toString();
			e.printStackTrace();
		}
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	public RetAtsSingle d_9144_QryRealTimeRec(ReqQrySingle p_req9144) throws Exception {
		if ("910801".equals(p_req9144.reqHeader.commandCode)) {
			return d_914401(p_req9144);
		} else {
			return d_914402(p_req9144);
		}
	}

	/**
	 * 宝付单笔实时代收状态查询
	 */
	public RetAtsSingle d_914401(ReqQrySingle p_req9144) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9144.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req9144);

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9144.recAct, "");
			if (actItem == null ) {
				throw new Exception("未找到账号" + p_req9144.recAct + "对应的商户配置信息");
			}

			Map<String,String> postParams = new HashMap<String,String>();

			postParams.put("version", "4.0.0.0");
			postParams.put("terminal_id", actItem.termId);
			postParams.put("txn_type", "0431");
			postParams.put("txn_sub_type", "31");
			postParams.put("member_id", actItem.merchantId);
			postParams.put("data_type", "xml");

			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\" ?>");
			xmlWriter.writeStartElement("data_content");
			xmlWriter.writeElementString("txn_sub_type", "31");
			xmlWriter.writeElementString("biz_type", "0000");
			xmlWriter.writeElementString("terminal_id", actItem.termId);
			xmlWriter.writeElementString("member_id", actItem.merchantId);
			xmlWriter.writeElementString("trans_serial_no", "TISN"+System.currentTimeMillis());
			xmlWriter.writeElementString("orig_trans_id", p_req9144.askNumber);
			xmlWriter.writeElementString("orig_trade_date", Format.DateTime14Format.format(p_req9144.getBgnDateTime()));
			xmlWriter.writeElementString("additional_info", "附加信息");
			xmlWriter.writeElementString("req_reserved", "保留");
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
			WriteBankLogLn2("加密数据: " + xmlWriter.toXmlString());

			String base64Str = Base64Encode(xmlWriter.toXmlString());
			String data_content = encryptByPriPfxFile(base64Str,actItem.ownKeyStorePath, actItem.ownKeyPassword);
			postParams.put("data_content", data_content);

			String tmpStrRet = sendToBank("9144", postParams);

			if (tmpStrRet.contains("trans_content")) {
				//明文返回,报文错误处理
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "报文参数设置错误";
			}else {
				String decryptStr = decryptByPubCerFile(tmpStrRet, actItem.oppCertFilePath);
				String  respXml = Base64Decode(decryptStr);
				WriteBankLogStep3(respXml);

				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
				if (tmpBkReader != null) {
					tmpRetDetail.respCode = "0";
					tmpRetDetail.respInfo = tmpBkReader.getFirstText("/result/resp_msg");
					if (StringHelper.hasAnyChar(tmpBkReader.getFirstText("/result/succ_amt"))) {
						tmpRetDetail.transAmt = StringHelper.amountDivide100(tmpBkReader.getFirstText("/result/succ_amt"));
					}

					String respCode = tmpBkReader.getFirstText("/result/resp_code");
					String status = tmpBkReader.getFirstText("/result/order_stat");
                    tmpRetDetail.transState = status;
                    tmpRetDetail.payInfoCode = respCode;
					if ("FF".equalsIgnoreCase(status)) {
                        if ("BF00128".equalsIgnoreCase(respCode)) {
                            if (canBeNotExist(p_req9144, tmpRetDetail, 45)) {
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.respInfo = "记录不存在!";
                                tmpRetDetail.transState = status;
                                tmpRetDetail.payInfoCode = respCode;
                                retAts.writeRetDetail(tmpRetDetail);
                                return retAts;
                            }
                        } else {
                            tmpRetDetail.respCode = "-1";
                        }
                    }
				}else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpSbMsg.toString();
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}
	public RetAtsSingle d_914402(ReqQrySingle p_req9144) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9144.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9144.recAct, "contract");
			if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath)|| !FileHelper.existFile(actItem.oppCertFilePath)) {
				if (actItem == null) {
					throw new Exception("未找到账号" + p_req9144.recAct + "对应的商户配置信息");
				} else {
					throw new Exception("账号" + p_req9144.recAct + "对应的证书文件不存在");
				}
			}

			Map<String,String> postParams = new TreeMap<String,String>();
			postParams.put("send_time", Format.DateTimeFormat.format(new Date()));
			postParams.put("msg_id", p_req9144.askNumber+"1");
			postParams.put("version", "4.0.0.0");
			postParams.put("terminal_id", actItem.termId);
			postParams.put("txn_type", "07");
			postParams.put("orig_trans_id", p_req9144.askNumber);
			postParams.put("orig_trade_date", Format.DateTimeFormat.format(p_req9144.getBgnDateTime()));
			postParams.put("member_id", actItem.merchantId);
			postParams.put("signature", sign(postParams,actItem));
			String[] tmpStrRet = sendToBank("contract", postParams, actItem);

			if (tmpStrRet[0].length() == 0) {
				Map<String, String> ReturnData = FormatUtil.getParm(tmpStrRet[1]);
				String resp_code = ReturnData.get("resp_code");
				String biz_resp_code = ReturnData.get("biz_resp_code");
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = ReturnData.get("biz_resp_msg");
				tmpRetDetail.transState = resp_code;
				tmpRetDetail.payInfoCode = biz_resp_code;
				tmpRetDetail.reqSeqID = p_req9144.askNumber;
				tmpRetDetail.transAmt =ReturnData.get("succ_amt")==null?"":StringHelper.amountDivide100(ReturnData.get("succ_amt"));
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception e) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = e.getMessage();
			e.printStackTrace();
		}

		if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
			tmpRetDetail.reqSeqID = p_req9144.askNumber;
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}
}
